{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Regressão Linear Multivariada - Trabalho\n",
    "\n",
    "## Estudo de caso: Qualidade de Vinhos\n",
    "\n",
    "Nesta trabalho, treinaremos um modelo de regressão linear usando descendência de gradiente estocástico no conjunto de dados da Qualidade do Vinho. O exemplo pressupõe que uma cópia CSV do conjunto de dados está no diretório de trabalho atual com o nome do arquivo *winequality-white.csv*.\n",
    "\n",
    "O conjunto de dados de qualidade do vinho envolve a previsão da qualidade dos vinhos brancos em uma escala, com medidas químicas de cada vinho. É um problema de classificação multiclasse, mas também pode ser enquadrado como um problema de regressão. O número de observações para cada classe não é equilibrado. Existem 4.898 observações com 11 variáveis de entrada e 1 variável de saída. Os nomes das variáveis são os seguintes:\n",
    "\n",
    "1. Fixed acidity.\n",
    "2. Volatile acidity.\n",
    "3. Citric acid.\n",
    "4. Residual sugar.\n",
    "5. Chlorides.\n",
    "6. Free sulfur dioxide. \n",
    "7. Total sulfur dioxide. \n",
    "8. Density.\n",
    "9. pH.\n",
    "10. Sulphates.\n",
    "11. Alcohol.\n",
    "12. Quality (score between 0 and 10).\n",
    "\n",
    "O desempenho de referencia de predição do valor médio é um RMSE de aproximadamente 0.148 pontos de qualidade.\n",
    "\n",
    "Utilize o exemplo apresentado no tutorial e altere-o de forma a carregar os dados e analisar a acurácia de sua solução. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 174,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#Importando bibliotecas\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn import preprocessing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 175,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>fixed acidity</th>\n",
       "      <th>volatile acidity</th>\n",
       "      <th>citric acid</th>\n",
       "      <th>residual sugar</th>\n",
       "      <th>chlorides</th>\n",
       "      <th>free sulfur dioxide</th>\n",
       "      <th>total sulfur dioxide</th>\n",
       "      <th>density</th>\n",
       "      <th>pH</th>\n",
       "      <th>sulphates</th>\n",
       "      <th>alcohol</th>\n",
       "      <th>quality</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7.0</td>\n",
       "      <td>0.27</td>\n",
       "      <td>0.36</td>\n",
       "      <td>20.7</td>\n",
       "      <td>0.045</td>\n",
       "      <td>45.0</td>\n",
       "      <td>170.0</td>\n",
       "      <td>1.0010</td>\n",
       "      <td>3.00</td>\n",
       "      <td>0.45</td>\n",
       "      <td>8.8</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6.3</td>\n",
       "      <td>0.30</td>\n",
       "      <td>0.34</td>\n",
       "      <td>1.6</td>\n",
       "      <td>0.049</td>\n",
       "      <td>14.0</td>\n",
       "      <td>132.0</td>\n",
       "      <td>0.9940</td>\n",
       "      <td>3.30</td>\n",
       "      <td>0.49</td>\n",
       "      <td>9.5</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>8.1</td>\n",
       "      <td>0.28</td>\n",
       "      <td>0.40</td>\n",
       "      <td>6.9</td>\n",
       "      <td>0.050</td>\n",
       "      <td>30.0</td>\n",
       "      <td>97.0</td>\n",
       "      <td>0.9951</td>\n",
       "      <td>3.26</td>\n",
       "      <td>0.44</td>\n",
       "      <td>10.1</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>7.2</td>\n",
       "      <td>0.23</td>\n",
       "      <td>0.32</td>\n",
       "      <td>8.5</td>\n",
       "      <td>0.058</td>\n",
       "      <td>47.0</td>\n",
       "      <td>186.0</td>\n",
       "      <td>0.9956</td>\n",
       "      <td>3.19</td>\n",
       "      <td>0.40</td>\n",
       "      <td>9.9</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>7.2</td>\n",
       "      <td>0.23</td>\n",
       "      <td>0.32</td>\n",
       "      <td>8.5</td>\n",
       "      <td>0.058</td>\n",
       "      <td>47.0</td>\n",
       "      <td>186.0</td>\n",
       "      <td>0.9956</td>\n",
       "      <td>3.19</td>\n",
       "      <td>0.40</td>\n",
       "      <td>9.9</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   fixed acidity  volatile acidity  citric acid  residual sugar  chlorides  \\\n",
       "0            7.0              0.27         0.36            20.7      0.045   \n",
       "1            6.3              0.30         0.34             1.6      0.049   \n",
       "2            8.1              0.28         0.40             6.9      0.050   \n",
       "3            7.2              0.23         0.32             8.5      0.058   \n",
       "4            7.2              0.23         0.32             8.5      0.058   \n",
       "\n",
       "   free sulfur dioxide  total sulfur dioxide  density    pH  sulphates  \\\n",
       "0                 45.0                 170.0   1.0010  3.00       0.45   \n",
       "1                 14.0                 132.0   0.9940  3.30       0.49   \n",
       "2                 30.0                  97.0   0.9951  3.26       0.44   \n",
       "3                 47.0                 186.0   0.9956  3.19       0.40   \n",
       "4                 47.0                 186.0   0.9956  3.19       0.40   \n",
       "\n",
       "   alcohol  quality  \n",
       "0      8.8        6  \n",
       "1      9.5        6  \n",
       "2     10.1        6  \n",
       "3      9.9        6  \n",
       "4      9.9        6  "
      ]
     },
     "execution_count": 175,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Lendo dataset\n",
    "data =  pd.read_csv('winequality-white.csv',delimiter=';')\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 176,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "      <th>5</th>\n",
       "      <th>6</th>\n",
       "      <th>7</th>\n",
       "      <th>8</th>\n",
       "      <th>9</th>\n",
       "      <th>10</th>\n",
       "      <th>11</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.307692</td>\n",
       "      <td>0.186275</td>\n",
       "      <td>0.216867</td>\n",
       "      <td>0.308282</td>\n",
       "      <td>0.106825</td>\n",
       "      <td>0.149826</td>\n",
       "      <td>0.373550</td>\n",
       "      <td>0.267785</td>\n",
       "      <td>0.254545</td>\n",
       "      <td>0.267442</td>\n",
       "      <td>0.129032</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.240385</td>\n",
       "      <td>0.215686</td>\n",
       "      <td>0.204819</td>\n",
       "      <td>0.015337</td>\n",
       "      <td>0.118694</td>\n",
       "      <td>0.041812</td>\n",
       "      <td>0.285383</td>\n",
       "      <td>0.132832</td>\n",
       "      <td>0.527273</td>\n",
       "      <td>0.313953</td>\n",
       "      <td>0.241935</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.413462</td>\n",
       "      <td>0.196078</td>\n",
       "      <td>0.240964</td>\n",
       "      <td>0.096626</td>\n",
       "      <td>0.121662</td>\n",
       "      <td>0.097561</td>\n",
       "      <td>0.204176</td>\n",
       "      <td>0.154039</td>\n",
       "      <td>0.490909</td>\n",
       "      <td>0.255814</td>\n",
       "      <td>0.338710</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.326923</td>\n",
       "      <td>0.147059</td>\n",
       "      <td>0.192771</td>\n",
       "      <td>0.121166</td>\n",
       "      <td>0.145401</td>\n",
       "      <td>0.156794</td>\n",
       "      <td>0.410673</td>\n",
       "      <td>0.163678</td>\n",
       "      <td>0.427273</td>\n",
       "      <td>0.209302</td>\n",
       "      <td>0.306452</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.326923</td>\n",
       "      <td>0.147059</td>\n",
       "      <td>0.192771</td>\n",
       "      <td>0.121166</td>\n",
       "      <td>0.145401</td>\n",
       "      <td>0.156794</td>\n",
       "      <td>0.410673</td>\n",
       "      <td>0.163678</td>\n",
       "      <td>0.427273</td>\n",
       "      <td>0.209302</td>\n",
       "      <td>0.306452</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         0         1         2         3         4         5         6   \\\n",
       "0  0.307692  0.186275  0.216867  0.308282  0.106825  0.149826  0.373550   \n",
       "1  0.240385  0.215686  0.204819  0.015337  0.118694  0.041812  0.285383   \n",
       "2  0.413462  0.196078  0.240964  0.096626  0.121662  0.097561  0.204176   \n",
       "3  0.326923  0.147059  0.192771  0.121166  0.145401  0.156794  0.410673   \n",
       "4  0.326923  0.147059  0.192771  0.121166  0.145401  0.156794  0.410673   \n",
       "\n",
       "         7         8         9         10   11  \n",
       "0  0.267785  0.254545  0.267442  0.129032  0.5  \n",
       "1  0.132832  0.527273  0.313953  0.241935  0.5  \n",
       "2  0.154039  0.490909  0.255814  0.338710  0.5  \n",
       "3  0.163678  0.427273  0.209302  0.306452  0.5  \n",
       "4  0.163678  0.427273  0.209302  0.306452  0.5  "
      ]
     },
     "execution_count": 176,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Normaliza os dados, para o gradiente convergir mais rápido. E todas as features ter o mesmo peso na função de custo \n",
    "x = data.values #returns a numpy array\n",
    "min_max_scaler = preprocessing.MinMaxScaler()\n",
    "x_scaled = min_max_scaler.fit_transform(data)\n",
    "data = pd.DataFrame(x_scaled)\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 177,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from math import sqrt\n",
    "\n",
    "# Calculate root mean squared error\n",
    "def rmse_metric(actual, predicted):\n",
    "    sum_error = 0.0\n",
    "    for i in range(len(actual)):\n",
    "        prediction_error = predicted[i] - actual[i]\n",
    "        sum_error += (prediction_error ** 2)\n",
    "        mean_error = sum_error / float(len(actual))\n",
    "    return sqrt(mean_error)\n",
    "\n",
    "# Estimate linear regression coefficients using stochastic gradient descent\n",
    "def coefficients_sgd(train, l_rate, n_epoch):\n",
    "    m = len(train)\n",
    "    cost = [0.0 for i in range(n_epoch)]\n",
    "    coef = [0.0 for i in range(len(train[0]))]\n",
    "    print ('Coeficiente Inicial={0}' % (coef))\n",
    "    for epoch in range(n_epoch):\n",
    "        sum_error = 0\n",
    "        for i,row in enumerate(train):            \n",
    "            yhat = predict(row, coef)\n",
    "            error = yhat - row[-1]\n",
    "            sum_error += (error**2)/m\n",
    "            coef[0] = coef[0] - l_rate * error\n",
    "            for i in range(len(row)-1):\n",
    "                coef[i + 1] = coef[i + 1] - l_rate * error * row[i] \n",
    "        print(('epoch=%d, lrate=%.3f, error=%.3f' % (epoch, l_rate, sum_error)))\n",
    "        predicts = [0.0 for i in range(len(train))]\n",
    "        for i,row in enumerate(df):\n",
    "            predicts[i] = predict(row, coef)\n",
    "        cost[epoch] = rmse_metric(train[-1],predicts)\n",
    "    return coef,cost\n",
    "\n",
    "# Example of making a prediction with coefficients\n",
    "# Make a prediction\n",
    "def predict(row, coefficients):\n",
    "    yhat = coefficients[0]\n",
    "    for i in range(len(row)-1):\n",
    "        yhat += coefficients[i + 1] * row[i]\n",
    "    return yhat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 178,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#Defini o passo de aprendizagem e o número de épocas\n",
    "lr = 0.001\n",
    "epoch = 50"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 179,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Coeficiente Inicial={0}\n",
      "epoch=0, lrate=0.001, error=0.033\n",
      "epoch=1, lrate=0.001, error=0.019\n",
      "epoch=2, lrate=0.001, error=0.019\n",
      "epoch=3, lrate=0.001, error=0.018\n",
      "epoch=4, lrate=0.001, error=0.018\n",
      "epoch=5, lrate=0.001, error=0.018\n",
      "epoch=6, lrate=0.001, error=0.017\n",
      "epoch=7, lrate=0.001, error=0.017\n",
      "epoch=8, lrate=0.001, error=0.017\n",
      "epoch=9, lrate=0.001, error=0.017\n",
      "epoch=10, lrate=0.001, error=0.017\n",
      "epoch=11, lrate=0.001, error=0.017\n",
      "epoch=12, lrate=0.001, error=0.017\n",
      "epoch=13, lrate=0.001, error=0.017\n",
      "epoch=14, lrate=0.001, error=0.017\n",
      "epoch=15, lrate=0.001, error=0.017\n",
      "epoch=16, lrate=0.001, error=0.017\n",
      "epoch=17, lrate=0.001, error=0.017\n",
      "epoch=18, lrate=0.001, error=0.016\n",
      "epoch=19, lrate=0.001, error=0.016\n",
      "epoch=20, lrate=0.001, error=0.016\n",
      "epoch=21, lrate=0.001, error=0.016\n",
      "epoch=22, lrate=0.001, error=0.016\n",
      "epoch=23, lrate=0.001, error=0.016\n",
      "epoch=24, lrate=0.001, error=0.016\n",
      "epoch=25, lrate=0.001, error=0.016\n",
      "epoch=26, lrate=0.001, error=0.016\n",
      "epoch=27, lrate=0.001, error=0.016\n",
      "epoch=28, lrate=0.001, error=0.016\n",
      "epoch=29, lrate=0.001, error=0.016\n",
      "epoch=30, lrate=0.001, error=0.016\n",
      "epoch=31, lrate=0.001, error=0.016\n",
      "epoch=32, lrate=0.001, error=0.016\n",
      "epoch=33, lrate=0.001, error=0.016\n",
      "epoch=34, lrate=0.001, error=0.016\n",
      "epoch=35, lrate=0.001, error=0.016\n",
      "epoch=36, lrate=0.001, error=0.016\n",
      "epoch=37, lrate=0.001, error=0.016\n",
      "epoch=38, lrate=0.001, error=0.016\n",
      "epoch=39, lrate=0.001, error=0.016\n",
      "epoch=40, lrate=0.001, error=0.016\n",
      "epoch=41, lrate=0.001, error=0.016\n",
      "epoch=42, lrate=0.001, error=0.016\n",
      "epoch=43, lrate=0.001, error=0.016\n",
      "epoch=44, lrate=0.001, error=0.016\n",
      "epoch=45, lrate=0.001, error=0.016\n",
      "epoch=46, lrate=0.001, error=0.016\n",
      "epoch=47, lrate=0.001, error=0.016\n",
      "epoch=48, lrate=0.001, error=0.016\n",
      "epoch=49, lrate=0.001, error=0.016\n"
     ]
    }
   ],
   "source": [
    "#Executa o regressão linear multvariável com gradiente estocástico\n",
    "[coefficients,cost] = coefficients_sgd(df,ls,epoch)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 180,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1fea09e93c8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(cost)\n",
    "plt.xlabel('Época')\n",
    "plt.ylabel('RMSE')\n",
    "plt.title('Erro por época')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 181,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Para lr = 0.001 e epoch = 50\n",
      "RMSE = 0.2838620445019942\n"
     ]
    }
   ],
   "source": [
    "print('Para lr = {0} e epoch = {1}\\nRMSE = {2}'.format(ls,epoch,cost[-1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "É possível observar através do gráfico de erro por época, que o algoritmo esta aprendendo. O erro foi próximo do esperado, mas não foi exato. Isto porque, foi utilizado o método do gradiente estocástico. Apesar do método convergir mais rápido para próximo do ponto de mínimo, ele fica variando muito em torno do mínimo. Uma solução seria utilizar o gradiente em lotes, que demora mais para convergir, porém não fica variando. Ou utilizar o método dos mínimos quadrados que chega no mínimo em uma interação. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Os dados de erro foram calculados no conjunto de treino. Caso fosse utilizado um conjunto de teste, o erro provavelmente seria maior, e poderia estar havendo overfitting. A solução para isto, seria utilizar regularização. "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
